package com.example.drzhang.oengldemo.render;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.util.Log;

import com.example.drzhang.oengldemo.R;
import com.example.drzhang.oengldemo.util.TextResourceReader;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * @author drzhang
 * @date 2018.1.6
 * 渲染器
 */
public class MyGLRender implements GLSurfaceView.Renderer {

    public static final String TAG = MyGLRender.class.getSimpleName();

    private Context mContext;
    public static final int BYTES_PER_FLOAT = 4;
    public static final int POSITION_COMPONENT_COUNT = 4;
    private final FloatBuffer vertexData;
    private int program;

    private static final String U_COLOR = "u_Color";
    private int uColorLocation;

    private static final String A_POSITION = "a_Position";
    private int aPositionLocation;

//    private float[] tableVerticles = {
//            -0.5f, -0.5f,
//            0.5f, 0.5f,
//            -0.5f, 0.5f,
//
//            -0.5f, -0.5f,
//            0.5f, -0.5f,
//            0.5f, 0.5f,
//
//            -0.5f, 0f,
//            0.5f, 0f,
//
//            0f, -0.25f,
//            0f, 0.25f
//    };

    private static final String A_COLOR = "a_Color";
    private static final int COLOR_COMPONENT_COUNT = 3;
    private static final int STRIDE = (POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT;
    private int aColorLocation;

    private static final String U_MATRIX = "u_Matrix";
    private int uMatrixLocation;
    private float[] projectionMatrix = new float[16];

    private float[] modelMatrix = new float[16];

    private float[] tableVerticles = {
            // x,     y ,  z, w,  R,    G,    B

               0f,    0f,  0f,  1.5f,   1f,   1f,   1f,
            -0.5f, -0.8f,  0f,  1.0f, 0.7f, 0.7f, 0.7f,
             0.5f, -0.8f,  0f,  1.0f, 0.7f, 0.7f, 0.7f,
             0.5f,  0.8f,  0f,  2.0f, 0.7f, 0.7f, 0.7f,
            -0.5f,  0.8f,  0f,  2.0f, 0.7f, 0.7f, 0.7f,
            -0.5f, -0.8f,  0f,  1.0f, 0.7f, 0.7f, 0.7f,


            -0.5f,    0f, 0f,  1.5f, 0.6f, 0.2f, 0.1f,
             0.5f,    0f, 0f,  1.5f, 0.7f, 0.8f, 0.5f,

               0f, -0.4f, 0f,  1.25f, 0.5f, 0.5f, 0.7f,
               0f,  0.4f, 0f,  1.75f, 0.4f, 0.8f, 0.7f
    };

    public MyGLRender(Context context) {
        this.mContext = context;
        //申请一块本地数据区域
        vertexData = ByteBuffer.allocateDirect(tableVerticles.length * BYTES_PER_FLOAT)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        //为该本地数据区域赋值
        vertexData.put(tableVerticles);
    }

    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        //清屏，整屏红色
//        GLES20.glClearColor(1.0f,0f,0f,0f);
        //清屏，整屏黑色
        GLES20.glClearColor(0.0f, 0f, 0f, 0f);

        //读取着色器
        String vertexShaderResource = TextResourceReader.readTextFileFromResource(mContext, R.raw.sample_vertex_shader);
        String fragmentShaderResource = TextResourceReader.readTextFileFromResource(mContext, R.raw.sample_fragment_shader);

        //编译着色器代码
        int vertexShader = ShaderHelper.compileVertexShader(vertexShaderResource);
        int fragmentShader = ShaderHelper.compileFragmentShader(fragmentShaderResource);

        //将编译后的着色器代码与着色器程序进行链接
        program = ShaderHelper.linkProgram(vertexShader, fragmentShader);

        //验证链接完成的着色器程序是否有效
        boolean validateResult = ShaderHelper.validateProgram(program);
        if (!validateResult) {
            Log.e(TAG, "program is invalid");
            return;
        }

        //使用着色器程序
        GLES20.glUseProgram(program);

//        uColorLocation = GLES20.glGetUniformLocation(program, U_COLOR);
//        aPositionLocation = GLES20.glGetAttribLocation(program, A_POSITION);
//
//        //缓冲区数组的指针复位，从第一个数据项开始
//        vertexData.position(0);
//        GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT,
//                false, 0, vertexData);
//        GLES20.glEnableVertexAttribArray(aPositionLocation);

        aPositionLocation = GLES20.glGetAttribLocation(program, A_POSITION);
        aColorLocation = GLES20.glGetAttribLocation(program, A_COLOR);
        uMatrixLocation = GLES20.glGetUniformLocation(program, U_MATRIX);

        vertexData.position(0);
        GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT,
                false, STRIDE, vertexData);
        vertexData.position(POSITION_COMPONENT_COUNT);
        GLES20.glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GLES20.GL_FLOAT,
                false, STRIDE, vertexData);

        GLES20.glEnableVertexAttribArray(aPositionLocation);
        GLES20.glEnableVertexAttribArray(aColorLocation);

    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        GLES20.glViewport(0, 0, width, height);

        //获取恒定的屏幕宽高比率，不管在竖屏还是横屏模式下该比率值是一样的
//        float aspectRatio = width > height ? (float) width / (float) height : (float) height / (float) width;
        //根据该比率一个相同的正交投影矩阵，忽略横竖屏造成的差异
//        if (width > height) {
//            Matrix.orthoM(projectionMatrix, 0, -aspectRatio, aspectRatio, -1.0f, 1.0f, -1.0f, 1.0f);
//        } else {
//            Matrix.orthoM(projectionMatrix, 0, -1.0f, 1.0f, -aspectRatio, aspectRatio, -1.0f, 1.0f);
//        }

        MatrixHelper.perspectiveM(projectionMatrix,45,(float) width/(float) height,1f, 10f);
        //将modelMatrix置为单位矩阵
        Matrix.setIdentityM(modelMatrix,0);
        //将该单位矩阵沿着z轴平移-2
        Matrix.translateM(modelMatrix,0,0f,0f, -2.5f);
        Matrix.rotateM(modelMatrix,0,-60f,1f,0f,0f);
        float[] temp = new float[16];
        Matrix.multiplyMM(temp,0,projectionMatrix,0,modelMatrix,0);
        System.arraycopy(temp,0,projectionMatrix,0,temp.length);

    }

    @Override
    public void onDrawFrame(GL10 gl10) {

        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        //将创建的正交投影矩阵传递给着色器对象
        GLES20.glUniformMatrix4fv(uMatrixLocation,1,false,projectionMatrix,0);

//        //更新着色器中的color
//        GLES20.glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);
//        //通知着色器画三角形，且三角形的顶点数为6个，即表示画2个三角形
//        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
//
//        //更新着色器中的color
//        GLES20.glUniform4f(uColorLocation, 1.0f, 0.2f, 0.2f, 1.0f);
//        //通知着色器画线
//        GLES20.glDrawArrays(GLES20.GL_LINES, 6, 2);
//
//        //更新着色器中的color
//        GLES20.glUniform4f(uColorLocation, 0.0f, 0.5f, 1.0f, 1.0f);
//        //通知着色器画点
//        GLES20.glDrawArrays(GLES20.GL_POINTS, 8, 1);
//
//        //更新着色器中的color
//        GLES20.glUniform4f(uColorLocation, 1.0f, 0.0f, 0.6f, 1.0f);
//        //通知着色器画点
//        GLES20.glDrawArrays(GLES20.GL_POINTS, 9, 1);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
        GLES20.glDrawArrays(GLES20.GL_LINES, 6, 2);
        GLES20.glDrawArrays(GLES20.GL_POINTS, 8, 1);
        GLES20.glDrawArrays(GLES20.GL_POINTS, 9, 1);

    }
}
